﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Microsoft.Forums.MicrosoftForumsProvider;

using Local = Microsoft.Forums.OfflineStore;
using Web = Microsoft.Forums.MicrosoftForumsProvider.Forums;

namespace Microsoft.Forums.Tests.MicrosoftForumsProvider
{
    /// <summary>
    /// Test the conversion from the Forum webservice objects to the local database object
    /// </summary>
    [TestFixture]
    public class DomainObjectConvertersTest
    {

        #region ForumResult Object Conversion Tests

        /// <summary>
        /// Check if a ForumResult object has all fields copied to Forum object
        /// </summary>
        [Test]
        public void ConvertOfForumResultSuccessfullyCopiesCorrectFields()
        {
            var forumResult = new Web.Forum();
            forumResult.ForumId = Guid.NewGuid();
            forumResult.UniqueName = "Name";
            forumResult.GroupType = Web.DiscussionGroupType.ModeratorPostingForum;
            forumResult.Description = "Description";
            forumResult.Language = "en-us";
            forumResult.BugTracking = true;
            forumResult.ModifiedOn = DateTime.Now;
            forumResult.IsPrivate = true;
            forumResult.IsLocked = true;
            forumResult.DisplayName = "The prettier name for the Forum";

            Local.Forum forum = DomainObjectConverters.Convert(forumResult);

            Assert.AreEqual(forumResult.ForumId, forum.Id);
            Assert.AreEqual(forumResult.UniqueName, forum.Name);
            Assert.AreEqual(forumResult.DisplayName, forum.DisplayName);
            Assert.AreEqual(forumResult.GroupType, (Web.DiscussionGroupType)forum.ForumType);
            Assert.AreEqual(forumResult.Description, forum.Description);
            Assert.AreEqual(forumResult.Language, forum.Language);
            Assert.AreEqual(forumResult.ModifiedOn, forum.ModifiedOn);
            Assert.AreEqual(forumResult.BugTracking, forum.IsBugTracked);
            Assert.AreEqual(forumResult.IsPrivate, forum.IsPrivate);
            Assert.AreEqual(forumResult.IsLocked, forum.IsLocked);
            Assert.AreEqual(MicrosoftForumsServiceProvider.ProviderGuid, forum.ForumServiceProviderId);
        }

        /// <summary>
        /// Test if exception is thrown on null ForumResult argument
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void ConvertOfNullForumResultThrowArgumentNullException()
        {
            Web.Forum forumResult = null;

            DomainObjectConverters.Convert(forumResult);
        }

        /// <summary>
        /// Test if exception is thrown on null Forum argument
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void CopyToThrowArgumentNullIfForumIsNull()
        {
            DomainObjectConverters.CopyTo(new Web.BriefForum(), null);
        }

        #endregion


        #region ThreadResult Object Conversion Tests

        /// <summary>
        /// Check if a ThreadResult object has all fields copied to Thread object
        /// </summary>
        [Test]
        public void ConvertOfThreadResultSuccessfullyCopiesCorrectFields()
        {
            var threadResult = new Web.BriefThread();
            threadResult.Id = Guid.NewGuid();
            threadResult.Topic = "Name";
            threadResult.ThreadType = Web.ThreadType.Question;
            threadResult.ForumId = Guid.NewGuid();
            threadResult.CreatedBy = new Web.BriefUser() { Id = Guid.NewGuid() };
            threadResult.CreatedOn = DateTime.Now;
            threadResult.ModifiedOn = DateTime.Now;
            threadResult.LastReplyDate = DateTime.Now;
            threadResult.LastReplyId = Guid.NewGuid();

           // threadResult.HelpfulVotes = 10;
            //threadResult.Popularity = 10;
            threadResult.TotalReplies = 10;
            threadResult.TotalViews = 10;
            //threadResult.HasDeleted = true;
            //threadResult.HasAbusive = true;
            //threadResult.HasProposedAnswers = true;
            threadResult.IsHelpful = true;
            threadResult.IsSticky = true;
            threadResult.StickyDate = DateTime.Now;
            threadResult.IsAnswered = true;
            threadResult.IsLocked = true;
            threadResult.RootMessageId = Guid.NewGuid();
            var thread = DomainObjectConverters.Convert(threadResult);

            Assert.AreEqual(threadResult.Id, thread.Id);
            Assert.AreEqual(threadResult.Topic, thread.Topic);
            Assert.AreEqual(threadResult.ThreadType, (Web.ThreadType)thread.ThreadType);
            Assert.AreEqual(threadResult.ForumId, thread.ForumId);
            Assert.AreEqual(threadResult.CreatedOn, thread.CreatedOn);
            Assert.AreEqual(threadResult.CreatedBy.Id, thread.CreatedById);
            Assert.AreEqual(threadResult.ModifiedOn, thread.ModifiedOn);
            Assert.AreEqual(threadResult.LastReplyDate, thread.LastReplyOn);
            Assert.AreEqual(threadResult.LastReplyId, thread.LastReplyId);
            //Assert.AreEqual(threadResult.HelpfulVotes, thread.HelpfulVotes);
            //Assert.AreEqual(threadResult.Popularity, thread.Popularity);
            Assert.AreEqual(threadResult.TotalReplies, thread.TotalReplies);
            Assert.AreEqual(threadResult.RootMessageId, thread.RootPostId);
            Assert.AreEqual(threadResult.TotalViews, thread.TotalViews);
           // Assert.AreEqual(threadResult.HasDeleted, thread.HasDeleted);
           // Assert.AreEqual(threadResult.HasAbusive, thread.HasAbusive);
           // Assert.AreEqual(threadResult.HasProposedAnswers, thread.HasProposedAnswers);
            Assert.AreEqual(threadResult.IsHelpful, thread.IsHelpful);
            Assert.AreEqual(threadResult.IsSticky, thread.IsSticky);
            Assert.AreEqual(threadResult.StickyDate, thread.StickyDate);
            Assert.AreEqual(threadResult.IsAnswered, thread.IsAnswered);
            Assert.AreEqual(threadResult.IsLocked, thread.IsLocked);
        }

        /// <summary>
        /// Test if exception is thrown on null ThreadResult argument
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void ConvertOfNullThreadResultThrowArgumentNullException()
        {
            Web.Thread threadResult = null;

            DomainObjectConverters.Convert(threadResult);
        }

        /// <summary>
        /// Test if exception is thrown on null Thread argument
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void CopyToThrowArgumentNullIfThreadIsNull()
        {
            DomainObjectConverters.CopyTo(new Web.BriefThread(), null);
        }

        #endregion


        #region MessageResult Object Conversion Tests
        /// <summary>
        /// Check if a MessageResult object has all fields copied to Post object
        /// </summary>
        [Test]
        public void ConvertOfMessageResultSuccessfullyCopiesCorrectFields()
        {
            Guid forumId = Guid.NewGuid();
            var messageResult = new Web.BriefMessage();
            messageResult.Id = Guid.NewGuid();
            messageResult.Subject = "Name";
            messageResult.MessageType = Web.MessageType.ProposedAnswer;
            messageResult.ParentId = Guid.NewGuid();
            messageResult.DiscussionId = Guid.NewGuid();
            messageResult.CreatedOn = DateTime.Now;
            messageResult.CreatedBy = new Web.BriefUser() { Id = Guid.NewGuid() };
            messageResult.ModifiedDate = DateTime.Now;
            messageResult.ModifiedBy = new Web.BriefUser() { Id = Guid.NewGuid() };
            messageResult.IsAbusive = true;
            messageResult.IsAnswer = true;
            messageResult.TotalReplies = 10;

            var post = DomainObjectConverters.Convert(messageResult, forumId);

            Assert.AreEqual(forumId, post.ForumId);
            Assert.AreEqual(messageResult.Id, post.Id);
            Assert.AreEqual(messageResult.Subject, post.Subject);
            Assert.AreEqual(messageResult.MessageType, (Web.MessageType)post.PostType);
            Assert.AreEqual(messageResult.DiscussionId, post.ThreadId);
            Assert.AreEqual(messageResult.ParentId, post.ParentId);
            Assert.AreEqual(messageResult.CreatedOn, post.CreatedOn);
            Assert.AreEqual(messageResult.CreatedBy.Id, post.CreatedBy.Id);
            Assert.AreEqual(messageResult.ModifiedDate, post.ModifiedOn);
            Assert.AreEqual(messageResult.ModifiedBy.Id, post.ModifiedBy.Id);
            Assert.AreEqual(messageResult.IsAbusive, post.IsAbusive);
            Assert.AreEqual(messageResult.IsAnswer, post.IsAnswer);
            Assert.AreEqual(messageResult.TotalReplies, post.TotalReplies);
        }



        /// <summary>
        /// Test if exception is thrown on null MessageResult argument
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void ConvertOfNullMessageResultThrowArgumentNullException()
        {
            Guid forumId = Guid.NewGuid();
            Web.BriefMessage messageResult = null;

            DomainObjectConverters.Convert(messageResult, forumId);
        }

        /// <summary>
        /// Test if exception is thrown on null Post argument
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void CopyToThrowArgumentNullIfPostIsNull()
        {
            DomainObjectConverters.CopyTo(new Web.Message(), null);
        }

        #endregion


        #region UserDataResult Object Conversion Tests
        /// <summary>
        /// Check if a UserDataResult object has all fields copied to User object
        /// </summary>
        [Test]
        public void ConvertOfUserDataResultSuccessfullyCopiesCorrectFields()
        {
            var userDataResult = new Web.BriefUser();
            userDataResult.Id = Guid.NewGuid();
            userDataResult.DisplayName = "asdfasdasd";
            userDataResult.IsMvp = true;
            userDataResult.IsMsft = false;
            userDataResult.IsInappropriate = true;
            userDataResult.JoinedDate = DateTime.Now;
            userDataResult.LastActiveDate = DateTime.Now;
            userDataResult.Points = 10;
            userDataResult.PostsCount = 111;
            userDataResult.Stars = 3;
            userDataResult.AnswersCount = 24;

            var user = DomainObjectConverters.Convert(userDataResult);

            Assert.AreEqual(userDataResult.Id, user.Id);
            Assert.AreEqual(userDataResult.DisplayName, user.DisplayName);
            Assert.AreEqual(userDataResult.IsMvp, user.IsMvp);
            Assert.AreEqual(userDataResult.IsMsft, user.IsMsft);
            Assert.AreEqual(userDataResult.IsInappropriate, user.IsInappropriate);
            Assert.AreEqual(userDataResult.JoinedDate, user.JoinedDate);
            Assert.AreEqual(userDataResult.LastActiveDate, user.LastActiveDate);
            Assert.AreEqual(userDataResult.Points, user.Points);
            Assert.AreEqual(userDataResult.PostsCount, user.PostsCount);
            Assert.AreEqual(userDataResult.Stars, user.Stars);
            Assert.AreEqual(userDataResult.AnswersCount, user.AnswersCount);
        }


        /// <summary>
        /// Test if exception is thrown on null UserDataResult argument
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void ConvertOfNullUserDataResultThrowArgumentNullException()
        {
            Web.BriefUser userDataResult = null;

            DomainObjectConverters.Convert(userDataResult);
        }

        /// <summary>
        /// Test if exception is thrown on null User argument
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void CopyToThrowArgumentNullIfUserIsNull()
        {
            DomainObjectConverters.CopyTo(new Web.BriefUser(), null);
        }

        #endregion
    }
}

